package com.googlecode.jvmpart.proc;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.googlecode.jvmpart.ProcessManager;
import com.googlecode.jvmpart.ProcessManagerFactory;
import com.googlecode.jvmpart.utils.ProcessId;

/**
 * The bootstrap of the seperated jvm process
 * @author chunzhan.he
 *
 */
public class MainBootstrap {
	private static final Log logger = LogFactory.getLog(MainBootstrap.class);
	private static final String PID = ProcessId.getPid();

	public static void main(String[] args) {
		if(args.length<3)
			throw new IllegalArgumentException("request arguments!");
		String clazz = args[0];
		String params = args[1];
		String ppid = args[2];
		long ppidTimestamp = Long.parseLong(args[3]);
		logger.info("Parent PID:"+ppid+" Child PID:"+PID);
		Map<String, String> noSensitiveParams = new HashMap<String, String>();
		Map<String,String> map = parseParams(params, ppid, noSensitiveParams);
		ProcessManager pMng =ProcessManagerFactory.getInstance();
		try {
			pMng.start(ppid, ppidTimestamp, PID, noSensitiveParams);
			JvmProcess jvm = (JvmProcess)Class.forName(clazz).newInstance();
			jvm.execute(ppid, map);
		} catch (Throwable e) {
			logger.error(noSensitiveParams, e);
			pMng.error(ppid, ppidTimestamp, PID, e);
			System.exit(JvmProcess.EXIT_CODE_FAILED);
		} finally {
			pMng.stop(ppid, ppidTimestamp, PID, noSensitiveParams);
		}
	}
	private static Map<String, String> parseParams(String args, String ppid, Map<String, String> noSensitiveMap) {
		try {
			args = URLDecoder.decode(args, JvmProcess.PARAMS_ENCODING);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		String[] params = args.split(JvmProcess.PARAMS_DELIMIT);
		Map<String, String> map = new HashMap<String, String>();
		for(String param:params) {
			String[] kv = param.split(JvmProcess.PARAMS_SEPERATER, 2);
			String key = kv[0];
			String value = kv[1];
			if(key.startsWith(JvmProcess.SENSITIVE_PREFIX))
				value = xorString(value, ppid);
			else noSensitiveMap.put(key, value);
			map.put(key, value);
		}
		return map;
	}
	public static String xorString(String value, String key) {
		 char[] keys=key.toCharArray(); 
        char[] mesg=value.toCharArray(); 

        int ml=mesg.length; 
        int kl=keys.length; 
        char[] newmsg=new char[ml]; 

        for (int i=0; i<ml; i++){ 
           newmsg[i]=(char)(mesg[i]^keys[i%kl]); 
        }
        mesg=null; keys=null; 
        return new String(newmsg); 
	}
}
